package messages;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import errors.DSError;

public class DSMessage implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5518969628986663415L;
	private DSMessageType type;
	private String targetId;
	private String originId;
	private DSError error;

	// mapping from key strings (temperature, ...) to values (1, 20 , 15)
	protected Map<String, String> keyValueMap;

	public DSMessage() {
		type = null;
		targetId = null;
		originId = null;
		keyValueMap = null;
		error = null;
	}
	
	public DSMessage(Map<String, String> propMap) {
		type = null;
		targetId = null;
		originId = null;
		keyValueMap = propMap;
		error = null;
	}

	public DSMessageType getType() {
		return type;
	}

	public void setType(DSMessageType type) {
		this.type = type;
	}

	public String getTargetId() {
		return targetId;
	}

	public void setTargetId(String targetAdress) {
		this.targetId = targetAdress;
	}

	public String getOriginId() {
		return originId;
	}

	public void setOriginId(String originAdress) {
		this.originId = originAdress;
	}
	
	/**
	 * adds a value for a key
	 */
	public void addValueForKey(String key, String value) {
		if (keyValueMap == null) {
			keyValueMap = new HashMap<String, String>();
		}

		keyValueMap.put(key, value);
	}

	/**
	 * gets a string value for a given key throws an exception, if no such key
	 * is contained or if the map is not initialized
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public String getStringValueForKey(String key) throws Exception {
		if (keyValueMap == null) {
			throw new Exception("The key-value map is not initialized!");
		} else {
			String ret = keyValueMap.get(key);
			if (ret == null) {
				throw new Exception("No value for key: " + key
						+ " is contained in the map!");
			}
			return ret;
		}
	}

	/**
	 * returns an int value for the given key, throws exceptions on parse
	 * errors, or if no value is contained in the map or if the map is not
	 * initialized
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public int getIntValueForKey(String key) throws Exception {
		if (keyValueMap == null) {
			throw new Exception("The key-value map is not initialized!");
		}
		String valString = keyValueMap.get(key);

		if (valString == null) {
			throw new Exception("No value for key: " + key
					+ " is contained in the map!");
		}

		int ret = 0;
		try {
			ret = Integer.parseInt(valString);
		} catch (NumberFormatException e) {
			throw new Exception("The value for key: " + key
					+ " could not be parsed!", e);
		}
		return ret;
	}

	public DSError getError() {
		return error;
	}

	public void setError(DSError err) {
		error = err;
	}
	
	public Map<String,String> getPropertyMap() {
		return this.keyValueMap;
	}

	public String toString() {
		String ret = "";
		ret += "type: " + type + "; ";
		ret += "originAdress: " + originId + " -> ";
		ret += "targetAdress: " + targetId + "; ";
		ret += "map: " + keyValueMap + "; ";
		ret += "error: " + error;
		return ret;
	}

}
